﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.Collections.ObjectModel;
using System.Data.Objects.DataClasses;
using System.Data.Common;
using System.Data;


namespace CCF20Model
{
    public class VehicleData
    {
        public Vehicle  MyVehicle { get; set; }
        public Device MyDevice { get; set; }
        public Customer MyCustomer { get; set; }
    }
    public class UrgentData
    {
        public DateTime HappenDate { get; set; }
        public string Name { get; set; }
        public string VehicleLicense { get; set; }
        public string IDCSimNumber { get; set; }
        public string MobilePhone { get; set; }
    }
    public class FaultCollection : ObservableCollection<Fault>
    {
        private CCF20Entities ccf20Entities;
        
        protected override void InsertItem(int index, Fault item)
        {
            base.InsertItem(index, item);
        }

        protected override void RemoveItem(int index)
        {
            base.RemoveItem(index);
        }
        public FaultCollection(IEnumerable<Fault> faults, CCF20Entities context)
            : base(faults)
        {
            ccf20Entities = context;
        }

    }
   
    public class VehicleModelCollection <T>: ObservableCollection<T>
    {
        private CCF20Entities ccf20Entities;

        protected override void InsertItem(int index, T item)
        {
            base.InsertItem(index, item);
        }

        protected override void RemoveItem(int index)
        {
            base.RemoveItem(index);
        }
        public VehicleModelCollection(IEnumerable<T> faults, CCF20Entities context)
            : base(faults)
        {
            ccf20Entities = context;
        }

    }

    public class VehicleModel
    {
        CCF20Entities ccf20Entities;

        public IQueryable<VehicleData> GetRegisteredVehicle()
        {
               //选择所有注册过的车子
                return from v in ccf20Entities.Vehicles
                       where v.Devices.FirstOrDefault().IsRegistered == true
                       orderby v.LatestActiveTime descending
                       select new VehicleData
                       {
                           MyVehicle = v,
                           MyCustomer = v.Customer,
                           MyDevice = v.Devices.FirstOrDefault()

                       };
            
        }
        
        
        // Get All Vehicles 
        public IQueryable<VehicleData> GetAllVehicles(bool IsActive)
        {
            if (IsActive)
            {
                //只选择目前至少有1种状况的车子
                return from v in ccf20Entities.Vehicles
                       where v.IsActive
                       orderby v.LatestActiveTime descending
                       select new VehicleData
                       {
                           MyVehicle = v,
                           MyCustomer = v.Customer,
                           MyDevice = v.Devices.FirstOrDefault()

                       };
            }
            else
            {
                //选择所有的车子，包括没有状况的车辆
                return from v in ccf20Entities.Vehicles
                       where v.Devices.FirstOrDefault().IsRegistered == true 
                       orderby v.LatestActiveTime descending
                       select new VehicleData
                       {
                           MyVehicle = v,
                           MyCustomer = v.Customer,
                           MyDevice = v.Devices.FirstOrDefault()

                       };
            }
        }
        //Customer Care only take the vehicle with confirmed faults
        //For maintenance we don't need confirm. 
        public IQueryable<VehicleData> GetVehiclesWithConfirmedFault()
        {
            return from v in ccf20Entities.Vehicles
                   where (((v.Faults.Count(f => f.IsActive) > 0) && (v.Faults.Count(f => f.IsConfirmed) > 0)) 
                            || v.VehicleMaintenanceHistories.Count(f=>f.IsActive)>0)
                   orderby v.LatestActiveTime descending
                   select new VehicleData
                   {
                       MyVehicle = v,
                       MyCustomer = v.Customer,
                       MyDevice = v.Devices.FirstOrDefault()
                   };
        }
        public FaultCollection GetFaultByVehicle(int vehicleID,bool IsActive, EnumFaultType faultType, bool IsConfirmed)
        {
            string MyFaultType = Enum.GetName(typeof(EnumFaultType), faultType);
            var query = from f in ccf20Entities.Faults
                        where (f.IsActive == IsActive && 
                               f.IsConfirmed ==IsConfirmed && 
                               f.VehicleID == vehicleID &&
                               f.FaultType == MyFaultType)
                        orderby f.HappenDate descending
                        select f;

            return new FaultCollection(query, this.ccf20Entities);
        }
        //车辆诊断模块，确认过的故障码
        public FaultCollection GetUnconfirmedFaultByVehicle(int vehicleID)
        {
            return GetFaultByVehicle(vehicleID, true, EnumFaultType.故障, false);
        }
        
        //客户关怀模块，确认过的故障码
        public FaultCollection GetConfirmedFaultByVehicle(int vehicleID)
        {
            return GetFaultByVehicle(vehicleID, true, EnumFaultType.故障, true);
            
        }

        //经理查询模块，所有故障码 包括已处理和未处理的
        public IQueryable<Fault> GetAllFaultByVehicle(int vehicleID)
        {
            return from f in ccf20Entities.Faults
                   where f.VehicleID == vehicleID && f.FaultType == "故障"
                   orderby f.HappenDate descending
                   select f;
        }

        //经理查询模块，所有撞车记录 包括已处理和未处理的 IsActive-- True:当前有撞车还未处理    False：无论是否处理，包括已经处理过的历史记录
        public IQueryable<Fault> GetCrashByVehicle(int vehicleID,bool IsActive)
        {
            if (IsActive)
            {
                return from f in ccf20Entities.Faults
                       where (f.IsActive && f.VehicleID == vehicleID && f.FaultType == "撞车")
                       orderby f.HappenDate descending
                       select f;
            }
            else
            {
                return from f in ccf20Entities.Faults
                       where (f.VehicleID == vehicleID && f.FaultType == "撞车")
                       orderby f.HappenDate descending
                       select f;
            }
        }
        public IQueryable<VehicleRepairHistory> GetRepairHistoryByVehicle(int vehicleID, bool IsActive)
        {
            if (IsActive)
            {
                // 正在维修
                return from f in ccf20Entities.VehicleRepairHistories
                       where (f.IsActive && f.VehicleID == vehicleID)
                       orderby f.InShopDate descending
                       select f;
            }
            else
            {
                //所有过去的维修记录 （包括现在）
                return from f in ccf20Entities.VehicleRepairHistories
                       where f.VehicleID == vehicleID
                       orderby f.InShopDate descending
                       select f;
            }
        }

        public VehicleModelCollection<ContactHistory> GetContactHistoryByVehicle(int vehicleID, bool IsActive)
        {
            if (IsActive)
            {
                var query = from c in ccf20Entities.ContactHistories
                               where (c.IsActive && c.VehicleID == vehicleID)
                               orderby c.ContactTime descending
                               select c;

                return new VehicleModelCollection<ContactHistory>(query, this.ccf20Entities);
            }
            else
            {
                var query = from c in ccf20Entities.ContactHistories
                               where (c.VehicleID == vehicleID)
                               orderby c.ContactTime descending
                               select c;
                return new VehicleModelCollection<ContactHistory>(query, this.ccf20Entities);
            }
            
        }
        public IQueryable<VehicleMaintenanceHistory> GetVehicleMaintenanceRequestByVehicle(int vehicleID,bool IsActive)
        {
            if (IsActive)
            {
                return from v in ccf20Entities.VehicleMaintenanceHistories
                       where (v.IsActive && v.VehicleID == vehicleID)
                       select v;
            }
            else
            {
                return from v in ccf20Entities.VehicleMaintenanceHistories
                       where (v.VehicleID == vehicleID)
                       select v;
            }
        }
        public IQueryable<VehicleMaintenanceRecord> GetVehicleMaintenanceRecordByVehicle(int vehicleID)
        {
            return from v in ccf20Entities.VehicleMaintenanceRecords
                   where v.VehicleID == vehicleID
                   orderby v.ActiveDate descending
                   select v;
        }
        
        public IQueryable<VehicleMaintenanceHistory> GetVehicleMaintenanceHistoryByVehicle(int vehicleID)
        {
            return from v in ccf20Entities.VehicleMaintenanceHistories
                   where v.VehicleID == vehicleID
                   orderby v.ReceiveDate descending
                   select v;
        }
        public VehicleModelCollection<SMSHistory> GetSMSHistoryByVehicle(int vehicleID, bool IsActive)
        {
            if (IsActive)
            {
                var query = from s in ccf20Entities.SMSHistories
                               where (s.IsActive && s.VehicleID == vehicleID)
                               orderby s.QueueTime descending
                               select s;

                return new VehicleModelCollection<SMSHistory>(query, this.ccf20Entities);
            }
            else
            {
                var query = from s in ccf20Entities.SMSHistories
                               where s.VehicleID == vehicleID
                               orderby s.QueueTime descending
                               select s;
                return new VehicleModelCollection<SMSHistory>(query, this.ccf20Entities);
            }

        }
        public VehicleModel()
        {
            ccf20Entities = new CCF20Entities();
            
        }
        
        public void Update()
        {
            ccf20Entities.SaveChanges();
        }

        private void UpdateFirstContactTime(Vehicle vehicle,VehicleRepairHistory repairHistory)
        {
            foreach (Fault fault in ccf20Entities.Faults.Where(f => f.IsActive && f.VehicleID == vehicle.VehicleID && f.FirstContactDate == null))
            {
                fault.FirstContactDate = DateTime.Now;
                fault.VehicleRepairHistoryID = repairHistory.VehicleRepairHistoryID;
            }
            foreach( VehicleMaintenanceHistory vmh in ccf20Entities.VehicleMaintenanceHistories.Where(m=>m.IsActive && m.VehicleID == vehicle.VehicleID && m.FirstContactDate == null))
            {
                vmh.FirstContactDate = DateTime.Now;
                vmh.VehicleRepairHistoryID = repairHistory.VehicleRepairHistoryID;
            }
        }


        public void AddContactHistoryForVehicle(Vehicle vehicle, ContactHistory ch)
        {
            VehicleRepairHistory repairHistory = VehicleRepairStart(vehicle,null);
            ch.VehicleRepairHistoryID = repairHistory.VehicleRepairHistoryID;
            ccf20Entities.ContactHistories.AddObject(ch);
            
            UpdateFirstContactTime(vehicle, repairHistory);
            ccf20Entities.SaveChanges();
            if (ch.ContactResult.Contains("拒绝"))
            {
                DeclineCustomer(vehicle, ch.ContactResult);

            }
        }
        public void AddSMSHistoryForVehicle(Vehicle vehicle, SMSHistory sh)
        {
            VehicleRepairHistory repairHistory = VehicleRepairStart(vehicle, null);
            sh.VehicleRepairHistoryID = repairHistory.VehicleRepairHistoryID;
            ccf20Entities.SMSHistories.AddObject(sh);
            UpdateFirstContactTime(vehicle, repairHistory);
            ccf20Entities.SaveChanges();
            
        }

        //客户回场
        public VehicleRepairHistory VehicleRepairStart(Vehicle vehicle,DateTime? inShopDate)
        {
            VehicleRepairHistory repairHistory = ccf20Entities.VehicleRepairHistories.Where(v => v.VehicleID == vehicle.VehicleID && v.IsActive).FirstOrDefault();
            if (repairHistory == null)
            {

                repairHistory = new VehicleRepairHistory()
                {
                    Vehicle = vehicle,
                    IsActive = true
                };
                ccf20Entities.VehicleRepairHistories.AddObject(repairHistory);
                
            }
            if (inShopDate != null)
            {
                repairHistory.InShopDate = inShopDate;
                ccf20Entities.SaveChanges();
            }
            return repairHistory;

        }
        //客户出场
        public void VehicleRepairEnd(Vehicle vehicle, int cost, string reason)
        {
            //客户必须先回场，才可以出场
            VehicleRepairHistory repairHistory = ccf20Entities.VehicleRepairHistories.Where(v => v.VehicleID == vehicle.VehicleID && v.IsActive).FirstOrDefault();
            if (repairHistory == null)
            {
                throw new Exception("没有找到客户回场记录，不可以出场");
            }

            repairHistory.OutShopDate = DateTime.Now;
            repairHistory.RepairCost = cost;
            repairHistory.CloseReason = reason;
            repairHistory.IsActive = false;
            //对于客户出场，我们需要Reset 与车辆相关的状态，
            ResetVehicle(vehicle, reason,repairHistory);
            

        }
        public void AddVehicleMaintenanceHistory(Vehicle vehicle, CombinedMaintenanceType combinedMaintenance,int serviceMileage)
        {
            VehicleRepairHistory repairHistory = VehicleRepairStart(vehicle,null);
            VehicleMaintenanceRecord vmr;
            if (combinedMaintenance.MaintenaceRecord != null)
            {
                vmr = ccf20Entities.VehicleMaintenanceRecords.Where(
                                v => v.VehicleMainTenanceRecordID == combinedMaintenance.MaintenaceRecord.VehicleMainTenanceRecordID)
                                .FirstOrDefault();
                
                //找到下一次的同一个保养项目
                VehicleMaintenanceRecord nextVMR = ccf20Entities.VehicleMaintenanceRecords.Where(
                                v => v.AnchiID == combinedMaintenance.MaintenaceRecord.AnchiID &&
                                     v.Priority == combinedMaintenance.MaintenaceRecord.Priority + 1)
                                     .FirstOrDefault();
                if (nextVMR != null)
                {
                    nextVMR.LastServiceDate = DateTime.Now;
                    nextVMR.LastServiceMileage = serviceMileage;
                    vmr.IsActive = false;
                }

            }
            else
            {
                //如果在出场时，用户选择了没有定制的其他保养项目，就把它自动加入定制保养里
                vmr = new VehicleMaintenanceRecord();
                ccf20Entities.VehicleMaintenanceRecords.AddObject(vmr);
                vmr.MaintenanceTypeID = combinedMaintenance.MaintenanceType.MaintenanceTypeID;
                vmr.Priority = combinedMaintenance.MaintenanceType.Priority;
                vmr.ServiceMileage = combinedMaintenance.MaintenanceType.ServiceMileage;
                vmr.ServicePeriod = combinedMaintenance.MaintenanceType.ServicePeriod;
                vmr.VehicleID = vehicle.VehicleID;
                vmr.IsActive = true;
            }
            vmr.LastServiceMileage = serviceMileage;
            vmr.LastServiceDate = DateTime.Now;
            AddVehicleMaintenanceHistory(vehicle, vmr, repairHistory.VehicleRepairHistoryID,serviceMileage);
            
        }
        private void AddVehicleMaintenanceHistory(Vehicle vehicle, VehicleMaintenanceRecord vehicleMaintenanceRecord, int repairHistoryID, int serviceMileage)
        {
            VehicleMaintenanceHistory vmh = ccf20Entities.VehicleMaintenanceHistories.Where(
                                                v => v.IsActive &&
                                                    v.VehicleID == vehicle.VehicleID &&
                                                    v.MaintenanceTypeID == vehicleMaintenanceRecord.MaintenanceTypeID)
                                                    .FirstOrDefault();
            if (vmh == null)
            {
                vmh = new VehicleMaintenanceHistory();
                ccf20Entities.VehicleMaintenanceHistories.AddObject(vmh);
                vmh.VehicleID = vehicle.VehicleID;
                vmh.MaintenanceTypeID = vehicleMaintenanceRecord.MaintenanceTypeID;
                vmh.HappenDate = DateTime.Now;
                vmh.ReceiveDate = DateTime.Now;
                vmh.LastServiceDate = vehicle.LastServcieDate;
                vmh.LastServiceMileage = vehicle.LastServiceMileage;
                vmh.EffectiveReceiveDate = DateTime.Now;
                vmh.CareScore = 0;
                vmh.Priority = vehicleMaintenanceRecord.Priority;
            }
            vmh.FirstContactDate = vmh.FirstContactDate ?? DateTime.Now;
            vmh.VehicleRepairHistoryID = repairHistoryID;
            vmh.CurrentMileage = serviceMileage;
            vmh.CloseDate = DateTime.Now;
            vmh.CloseReason = "客户出场";
            vmh.IsActive = false;
            
            ccf20Entities.SaveChanges();

        }
        public void DeclineCustomer(Vehicle vehicle,string reason)
        {
            //对于拒绝或放弃的客户，模拟回场与出场
            VehicleRepairHistory vrh= VehicleRepairStart(vehicle,null);
            //对于对于拒绝或放弃的客户，我们需要Reset 与车辆相关的状态，
            //同时虚拟保养项目的处理
            //HandleMaintenanceRecord(vehicle, reason);
            //ResetVehicle(vehicle, reason);
            VehicleRepairEnd(vehicle, 0, reason);
        }
        public void RestoreCustomer(Vehicle vehicle)
        {
            vehicle.LastContactResult = Enum.GetName(typeof(EnumContactResult), EnumContactResult.未联系);
            ccf20Entities.SaveChanges();
            ContactHistory ch = new ContactHistory();
            ch.ContactResult = "恢复客户";
            ch.ContactTime = DateTime.Now;
            ch.VehicleID = vehicle.VehicleID;
            ch.Operator = vehicle.Operator;
            AddContactHistoryForVehicle(vehicle, ch);

        }
        public void GiveUpCustomer(Vehicle vehicle)
        {
            string reason = Enum.GetName(typeof(EnumContactResult),EnumContactResult.放弃客户);
            //对于拒绝或放弃的客户，模拟回场与出场
            VehicleRepairStart(vehicle,null);
            ccf20Entities.SaveChanges();

            ContactHistory ch = new ContactHistory();
            ch.ContactResult = reason;
            ch.ContactTime = DateTime.Now;
            ch.VehicleID = vehicle.VehicleID;
            ch.Operator = vehicle.Operator;
            AddContactHistoryForVehicle(vehicle, ch);

            
            
            //HandleMaintenanceRecord(vehicle, reason);
            //ResetVehicle(vehicle, reason);
            VehicleRepairEnd(vehicle, 0, reason);
        }
        public void RemoveUrgent(Vehicle vehicle)
        {
            foreach (Fault fault in vehicle.Faults.Where(f => f.FaultType == "撞车" && f.IsActive))
            {
                fault.IsActive = false;
                fault.FirstContactDate = DateTime.Now;
                fault.CloseDate = DateTime.Now;
                fault.CloseReason = "排除急救";
            }
            ccf20Entities.SaveChanges();
        }
        //public void HandleMaintenanceRecord(Vehicle vehicle, string reason)
        //{
        //    VehicleRepairHistory vrh = VehicleRepairStart(vehicle);
        //    foreach (VehicleMaintenanceRecord vmr in vehicle.VehicleMaintenanceRecords)
        //    {
        //        AddVehicleMaintenanceHistory(vehicle, vmr.MaintenanceType,vrh,reason);
        //    }
        //    ccf20Entities.SaveChanges();
        //}
        public void ResetVehicle(Vehicle vehicle,string reason, VehicleRepairHistory vrh)
        {
            
            // reset vehicle table vehiclestatus
            vehicle.IsActive = false;
            vehicle.IsFault = false;
            vehicle.IsMaintenance = false;
            vehicle.IsUrgent = false;
            vehicle.LastContactResult = reason;
            vehicle.LastContactTime = DateTime.Now;

            

            // clear faults table
            // clear VehicleMaintenanceHistoryTable
            // clear smshistory
            // clear contacthistory
            // Reset vehicleMaintenanceRecord (LastServiceMileage, LastServiceDate)
            //    *** we shouldn't reset vehicleMaintenanceRecord when 客户出场
            //    *** 客户出场时，我们基于客户所选取的保养项目进行维护项目的重置。
            
            
            foreach (ContactHistory ch in vehicle.ContactHistories.Where(c => c.IsActive))
            {
                ch.IsActive = false;
                ch.CloseDate = DateTime.Now;
                ch.VehicleRepairHistoryID = vrh.VehicleRepairHistoryID;
                ch.CloseReason = reason;
                ch.Operator = vehicle.Operator;
            }
            foreach (SMSHistory ch in vehicle.SMSHistories.Where(c => c.IsActive))
            {
                ch.IsActive = false;
                ch.CloseDate = DateTime.Now;
                ch.VehicleRepairHistoryID = vrh.VehicleRepairHistoryID;
                ch.CloseReason = reason;
                ch.Operator = vehicle.Operator;
            }
            foreach (Fault ch in vehicle.Faults.Where(c => c.IsActive))
            {
                ch.IsActive = false;
                ch.CloseDate = DateTime.Now;
                if (ch.FirstContactDate == null) ch.FirstContactDate = DateTime.Now;
                ch.VehicleRepairHistoryID = vrh.VehicleRepairHistoryID;
                ch.CloseReason = reason;
                ch.Operator = vehicle.Operator;
            }
            foreach (VehicleMaintenanceHistory ch in vehicle.VehicleMaintenanceHistories.Where(c => c.IsActive))
            {
                ch.IsActive = false;
                ch.CloseDate = DateTime.Now;
                ch.CloseReason = reason;
                ch.VehicleRepairHistoryID = vrh.VehicleRepairHistoryID;
                ch.CurrentMileage = vehicle.CurrentMileage;
                ch.Operator = vehicle.Operator;
                if (ch.FirstContactDate == null) ch.FirstContactDate = DateTime.Now;

            }
            if (reason != "客户实际出场")
            {
                foreach (VehicleMaintenanceRecord vmr in vehicle.VehicleMaintenanceRecords)
                {
                    vmr.LastServiceDate = DateTime.Now;
                    vmr.LastServiceMileage = vehicle.CurrentMileage;
                    vmr.Operator = vehicle.Operator;
                }
            }
            ccf20Entities.SaveChanges();
        }
        public void ExecuteSql(CCF20Entities c, string sql) 
        {
            if (c == null) c = this.ccf20Entities;
            var entityConnection = (System.Data.EntityClient.EntityConnection)c.Connection;
            DbConnection conn = entityConnection.StoreConnection;      
            ConnectionState initialState = conn.State;     
            try     
            { 
                if (initialState != ConnectionState.Open)        
                    conn.Open();  // open connection if not already open          
                using (DbCommand cmd = conn.CreateCommand())       
                {              
                    cmd.CommandText = sql;        
                    cmd.ExecuteNonQuery();          
                }
            }
            finally 
            { 
                if (initialState != ConnectionState.Open)   
                    conn.Close(); // only close connection if not initially open  
            }
        } 
    }
}
